﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
using Conditional = System.Diagnostics.ConditionalAttribute;

[CreateAssetMenu(menuName ="Rendering/Custom")]
public class CustomRenderPiplineAsset : RenderPipelineAsset
{
    [SerializeField]
    CustomPiplineSetting setting = new CustomPiplineSetting();

    [SerializeField, HideInInspector]
    float twoCascadesSplit = 0.25f;

    [SerializeField, HideInInspector]
    Vector3 fourCascadesSplit = new Vector3(0.067f, 0.2f, 0.467f);

    [SerializeField ]
    ShadowCascades shadowCascades = ShadowCascades.Zero;



    protected override IRenderPipeline InternalCreatePipeline()
    {
        
        setting.Init();
        setting.SetShadowCascades(shadowCascades, twoCascadesSplit, fourCascadesSplit);
        setting.shadowMapSize = (int)setting.shadowMapEnum;
        return new CustomRenderer(setting);
    }

    public enum ShadowCascades
    {
        Zero=0,
        Two =2,
        Four=4
    }
    public enum ShadowMapSize
    {
        None = 0,
        _256=256,
        _512=512,
        _1024=1024,
        _2048=2048,
        _4096=4096
    }
}




[System.Serializable]
public struct CustomPiplineSetting
{
    public bool dynamicBatching;
    public bool instancing;
    public CustomRenderPiplineAsset.ShadowMapSize shadowMapEnum;
    public int shadowDistance;
    public int shadowMapSize;

    public int _shadowCascades;
    public Vector3 shadowCascadeSplit;

    public void SetShadowCascades(CustomRenderPiplineAsset.ShadowCascades cascades,float twoShadowCascades,Vector3 fourShadowCascades)
    {
        _shadowCascades = (int)cascades;
        shadowCascadeSplit = cascades == CustomRenderPiplineAsset.ShadowCascades.Four ? fourShadowCascades : new Vector3(twoShadowCascades, 0);
    }
    public void Init()
    {
        if (shadowMapEnum == CustomRenderPiplineAsset.ShadowMapSize.None)
            shadowMapEnum = CustomRenderPiplineAsset.ShadowMapSize._256;
        shadowDistance = shadowDistance == 0 ? 100 : shadowDistance;
    }

}

public class CustomRenderer : RenderPipeline
{
    Renderer renderer;

    public CustomRenderer( CustomPiplineSetting setting)
    {
        GraphicsSettings.lightsUseLinearIntensity = true;
        renderer = new Renderer(setting);
    }

    public override void Render(ScriptableRenderContext renderContext, Camera[] cameras)
    {
        
        base.Render(renderContext, cameras);
        foreach (var i in cameras)
        {
            renderer.Render(renderContext, i);
        }
    }




}

public class Renderer
{
    ScriptableRenderContext contex;
    Camera camera;
    CullResults cull;
    CommandBuffer buffer = new CommandBuffer() { name = "RenderCamera"};
    string bufferName ="RenderCamera";
    Material errorMaterial;
    CustomPiplineSetting setting;




    #region Light 
    const int maxVisibleLights = 16;
    static int visibleLightColorId = Shader.PropertyToID("_VisibleLightColors");
    static int visibleLightDirectionOrPositionId = Shader.PropertyToID("_VisibleLightDirectionOrPosition");
    static int visibleLightAttenuationID = Shader.PropertyToID("_VisibleLightAttenuations");
    static int visibleLightSpotDirectionID = Shader.PropertyToID("_VisibleLightSpotDirections");
    static int lightIndicesOffsetAndCountId = Shader.PropertyToID("unity_LightIndicesOffsetAndCount");
    Vector4[] visibleLightColors = new Vector4[maxVisibleLights];
    Vector4[] visibleLightDirectionOrPosition = new Vector4[maxVisibleLights];
    Vector4[] visibleLightAttenuations = new Vector4[maxVisibleLights];
    Vector4[] visibleLightSpotDirections = new Vector4[maxVisibleLights];
    #endregion


    #region Shadow 



    static int shadowMapId= Shader.PropertyToID("_ShadowMap");
    static int worldToShadowMatricesId = Shader.PropertyToID("_WorldToShadowMatrices");
    static int shadowViewMatrixId = Shader.PropertyToID("_ShadowView");
    static int shadowProjectMatrixId = Shader.PropertyToID("_ShadowProject");
    static int shadowBissId = Shader.PropertyToID("_ShadowBias");
    static int shadowDataId = Shader.PropertyToID("_ShadowData");
    static int shadowMapSizeId = Shader.PropertyToID("_ShadowMapSize");
    static int globalShadowDataId = Shader.PropertyToID("_GlobalShadowData");
    static int cascadedShadowMapId = Shader.PropertyToID("_CascadeShadowMap");
    static int worldToShadowCascadeMatrixsID = Shader.PropertyToID("_WorldToShadowCascadeMatrices"); // 级联贴图的矩阵
    static int cascadedShadowMapSizeId = Shader.PropertyToID("_CascadeShadowMapSize");
    static int cascadedShadowStrengthId = Shader.PropertyToID("_CascadeShadowStrength");
    static int cascadedCullingSpheresId = Shader.PropertyToID("_CascadeCullingSpheres");
    
//_CascadeShadowStrength


    const string cascadedShadowHardKeyword = "_CASCADED_SHADOWS_HARD";
    const string cascadedShadowSoftKeyword = "_CASCADED_SHADOWS_SOFT";
    const string shadowSoftKeyWord = "_SHADOWS_SOFT";
    const string shadowHardKeyWord = "_SHADOWS_HARD";

    int shadowTileCount =0;
    Vector4[] shadowData=new Vector4[maxVisibleLights]; //存储灯光组阴影信息  x:阴影强度，y：软阴影：1/硬阴影：0 
    Vector4[] cascadedCullingSpheres = new Vector4[4];
    Matrix4x4[] worldToshadowMatrices = new Matrix4x4[maxVisibleLights];  //存储每个灯光的vp矩阵 
    Matrix4x4[] worldToShadowCascadeMatrices = new Matrix4x4[5];           //  仅支持四个级联阴影 所以长度为5 最后一个为0 

    RenderTexture shadowMap,cascadedShadowMap;
    CommandBuffer shadowBuffer = new CommandBuffer() { name = "Render Shadow" };
    string RenderShadow = "RenderShadows";

    int GetShadowMapSplit()
    {
        if (shadowTileCount <= 1)
        {
            return 1;
        }else if(shadowTileCount <= 4)
        {
            return 2;
        }else if(shadowTileCount <= 9)
        {
            return 3;
        }
        return 4;
    }

    //取得阴影数据
    Vector4 ConfigureShadows(int lightIndex,Light shadowLight)
    {
        Vector4 shadow = Vector4.zero;
        Bounds shadowBounds;
        if (shadowLight.shadows != LightShadows.None && cull.GetShadowCasterBounds(lightIndex,out shadowBounds))
        {
            shadowTileCount += 1;
            shadow.x = shadowLight.shadowStrength;
            shadow.y = shadowLight.shadows == LightShadows.Soft ? 1 : 0;
        }
        return shadow;
    }
    // 进行阴影渲染以及全局数据传输   为了每个灯光进行ShadowMap绘制
    
    void RenderShadows(ScriptableRenderContext context)
    {
        int split = GetShadowMapSplit(); 
        float tileSize = setting.shadowMapSize / split;
        float tileScale = 1f / split; //分割缩放比
        bool hardShadow = false;
        bool softShadow = false;
        bool vaildShadow=false; //有效阴影
        int tileIndex = 0;

        //设置ShadowMap参数
        shadowMap = SetShadowRenderTarget();
        //起始标记命令
        shadowBuffer.BeginSample(RenderShadow);
        shadowBuffer.SetGlobalVector(globalShadowDataId, new Vector4(tileScale, setting.shadowDistance*setting.shadowDistance));
        contex.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();

        //跳过首个灯光
        for (int i = mainLightExitst ? 1 : 0; i < cull.visibleLights.Count; i++)
        {

            if (i == maxVisibleLights) break;
            if (shadowData[i].x <= 0) continue;

            Matrix4x4 viewMatrix, projectMatirx;
            ShadowSplitData shadowSplit;

            //通过cull结果 取得当前聚光灯的信息 视图矩阵，投影矩阵。
            //根据shadowData的z分量判断当前按灯光是否为方向光
            if (shadowData[i].z == 1)
                vaildShadow = cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(i, 0, 1, Vector3.right, (int)tileSize, cull.visibleLights[i].light.shadowNearPlane, out viewMatrix, out projectMatirx, out shadowSplit);
            else
                vaildShadow = cull.ComputeSpotShadowMatricesAndCullingPrimitives(i, out viewMatrix, out projectMatirx, out shadowSplit);

            if (!vaildShadow)
            {
                shadowData[i].x = 0;
                continue;
            }

            if (shadowData[i].y <= 0) hardShadow = true;
            else softShadow = true;

            Vector2 tileOffset = ConfigureShadowTile(tileIndex, split, tileSize);

            shadowData[i].z = tileOffset.x * tileScale; //记录偏移量
            shadowData[i].w = tileOffset.y * tileScale; //记录偏移量 
            shadowBuffer.SetGlobalVectorArray(shadowDataId, shadowData);

            shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectMatirx); //设置此buff的视图矩阵与投影矩阵

            shadowBuffer.SetGlobalFloat(shadowBissId, cull.visibleLights[i].light.shadowBias);

            float invShadowMapSize = 1f / setting.shadowMapSize;
            shadowBuffer.SetGlobalVector(shadowMapSizeId, new Vector4(invShadowMapSize, invShadowMapSize, setting.shadowMapSize, setting.shadowMapSize));

            contex.ExecuteCommandBuffer(shadowBuffer);
            shadowBuffer.Clear();

            var shadowSetting = new DrawShadowsSettings(cull, i);  //通过cull信息初始化Shadow Setting
            shadowSetting.splitData.cullingSphere = shadowSplit.cullingSphere;
            contex.DrawShadows(ref shadowSetting); //绘制深度片面

            CalculateWorldToShadowMatrix(ref viewMatrix, ref projectMatirx, out worldToshadowMatrices[i]);

            tileIndex += 1;
            //设置是否激活软阴影
        }


        CoreUtils.SetKeyword(shadowBuffer, shadowSoftKeyWord, softShadow);
        CoreUtils.SetKeyword(shadowBuffer, shadowHardKeyWord, hardShadow);
        shadowBuffer.SetGlobalMatrixArray(worldToShadowMatricesId,worldToshadowMatrices);
        shadowBuffer.SetGlobalVectorArray(shadowDataId, shadowData);
        shadowBuffer.DisableScissorRect();
        shadowBuffer.SetGlobalTexture(shadowMapId, shadowMap); //设置全局贴图 ShadowMap
        //buffer传递结束命令 美化FrameDebug
        shadowBuffer.EndSample(RenderShadow);
        contex.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();

    }

    void RenderCascadsShadows(ScriptableRenderContext context)
    {

        if (!cull.GetShadowCasterBounds(0, out Bounds bounds)) return;
        float tileSize = setting.shadowMapSize / 2;
        cascadedShadowMap = SetShadowRenderTarget();

        shadowBuffer.BeginSample("SetShadowRenderTarget");
        context.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();
//
        Light shadowLight = cull.visibleLights[0].light;
        shadowBuffer.SetGlobalFloat(shadowBissId, shadowLight.shadowBias);

        var shadowSetting = new DrawShadowsSettings(cull, 0);
        var tileMatrix = Matrix4x4.identity;
        tileMatrix.m00 = tileMatrix.m11 = 0.5f;
        for (int i = 0; i < setting._shadowCascades; i++)
        {
            Matrix4x4 viewMatrix, projectionMatrix;
            ShadowSplitData SplitData;
            //取得当前灯光的M P矩阵 同时取得裁剪数据 splitData
            cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(0, i, (int)setting._shadowCascades, setting.shadowCascadeSplit,(int)tileSize , shadowLight.shadowNearPlane
                , out viewMatrix, out projectionMatrix, out SplitData);

            Vector2 tileoffset = ConfigureShadowTile(i, 2, tileSize);
            shadowBuffer.SetViewProjectionMatrices(viewMatrix,projectionMatrix);
            contex.ExecuteCommandBuffer(shadowBuffer);
            shadowBuffer.Clear();

            //绘制灯光当前级联阴影
            cascadedCullingSpheres[i] = shadowSetting.splitData.cullingSphere = SplitData.cullingSphere;
            cascadedCullingSpheres[i].w *= SplitData.cullingSphere.w;
            contex.DrawShadows(ref shadowSetting);
            CalculateWorldToShadowMatrix(ref viewMatrix, ref projectionMatrix, out worldToShadowCascadeMatrices[i]);
            tileMatrix.m03 = tileoffset.x * 0.5f;
            tileMatrix.m13 = tileoffset.y * 0.5f;
            worldToShadowCascadeMatrices[i] = tileMatrix * worldToShadowCascadeMatrices[i];
        }


        shadowBuffer.DisableScissorRect();
        shadowBuffer.SetGlobalTexture(cascadedShadowMapId, cascadedShadowMap); //级联裁剪坐标
        shadowBuffer.SetGlobalVectorArray(cascadedCullingSpheresId, cascadedCullingSpheres);
        shadowBuffer.SetGlobalMatrixArray(worldToShadowCascadeMatrixsID, worldToShadowCascadeMatrices);
        shadowBuffer.SetGlobalFloat(cascadedShadowStrengthId, cull.visibleLights[0].light.shadowStrength);
        float invShadowMapSize = 1 / setting.shadowMapSize;
        shadowBuffer.SetGlobalVector(cascadedShadowMapSizeId, new Vector4(invShadowMapSize, invShadowMapSize, setting.shadowMapSize, setting.shadowMapSize));
        bool hard = shadowLight.shadows == LightShadows.Hard;
        CoreUtils.SetKeyword(shadowBuffer, cascadedShadowHardKeyword, hard);
        CoreUtils.SetKeyword(shadowBuffer, cascadedShadowSoftKeyword, hard);
        shadowBuffer.EndSample("SetShadowRenderTarget");
        contex.ExecuteCommandBuffer(shadowBuffer);
        shadowBuffer.Clear();


    }

    //渲染结束后对RenderTexture进行缓存清除
    void ClearShadowsMap()
    {
        if (shadowMap)
        {
            RenderTexture.ReleaseTemporary(shadowMap);
            shadowMap = null;
        }
        if (cascadedShadowMap)
        {
            RenderTexture.ReleaseTemporary(cascadedShadowMap);
            cascadedShadowMap = null;
        }
    }
    RenderTexture SetShadowRenderTarget()
    {
        RenderTexture texture = RenderTexture.GetTemporary(setting.shadowMapSize, setting.shadowMapSize, 16, RenderTextureFormat.Depth);
        texture.filterMode = FilterMode.Bilinear;
        texture.wrapMode = TextureWrapMode.Clamp;
        CoreUtils.SetRenderTarget(shadowBuffer, texture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.Depth);
        return texture;
    }
    Vector2 ConfigureShadowTile(int tileIndex,int split,float tileSize)
    {
        Vector2 tileOffset;
        tileOffset.x = tileIndex % split;
        tileOffset.y = tileIndex / split;
        var tileViewPort = new Rect(tileOffset.x * tileSize, tileOffset.y * tileSize, tileSize, tileSize);
        shadowBuffer.SetViewport(tileViewPort);
        shadowBuffer.EnableScissorRect(new Rect(tileViewPort.x + 4f, tileViewPort.y + 4f, tileSize - 8f, tileSize - 8f));
        return tileOffset;
    }

    void CalculateWorldToShadowMatrix(ref Matrix4x4 viewMatrix, ref Matrix4x4 projectMatrix, out Matrix4x4 worldToShadowMatrix)
    {
        if (SystemInfo.usesReversedZBuffer)
        {
            projectMatrix.m20 = -projectMatrix.m20;
            projectMatrix.m21 = -projectMatrix.m21;
            projectMatrix.m22 = -projectMatrix.m22;
            projectMatrix.m23 = -projectMatrix.m23;

        }

        var scaleOffset = Matrix4x4.identity;
        scaleOffset.m00 = scaleOffset.m11 = scaleOffset.m22 = 0.5f;
        scaleOffset.m03 = scaleOffset.m13 = scaleOffset.m23 = 0.5f;

        worldToShadowMatrix = scaleOffset * (projectMatrix * viewMatrix);


    }



    #endregion 

    public Renderer(CustomPiplineSetting setting )
    {
        this.setting = setting;
        worldToShadowCascadeMatrices[4].m33 = 1f;
    }

    public void Render(ScriptableRenderContext contex, Camera camera)
    {
        this.contex = contex;
        this.camera = camera;

        if (!CullTest()) return;
        Setup();
        SetLight();
        DrawVisibleGeometry(cull);
        DrawDefaultPipeline(contex,camera);
        Submit();
        ClearShadowsMap();

    }


    bool CullTest()
    {
        if(CullResults.GetCullingParameters(camera, out ScriptableCullingParameters p))
        {
            #if UNITY_EDITOR 
            if (camera.cameraType == CameraType.SceneView)
            {
                ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);
            }
#endif
            p.shadowDistance = Mathf.Min(setting.shadowDistance, camera.farClipPlane);
            CullResults.Cull(ref p, contex, ref cull);

            return true;
        }
        return false;
    }

    //灯光数据传输至buffer中 提供给shader使用
    void SetLight()
    {
        buffer.BeginSample(bufferName);
        buffer.SetGlobalVectorArray(visibleLightColorId, visibleLightColors);
        buffer.SetGlobalVectorArray(visibleLightDirectionOrPositionId, visibleLightDirectionOrPosition);
        buffer.SetGlobalVectorArray(visibleLightAttenuationID, visibleLightAttenuations);
        buffer.SetGlobalVectorArray(visibleLightSpotDirectionID, visibleLightSpotDirections);
        ExcuteBuffer();
        buffer.EndSample(bufferName);
    }

    //灯光数据传入缓存数组
    //
    bool mainLightExitst;
    /// <summary>
    /// 灯光信息写入
    /// </summary>
    void ConfigureLights()
    {
        int i = 0;
        Vector4 attenuation = Vector4.zero;
        mainLightExitst = false;
        shadowTileCount = 0;

        for (; i < cull.visibleLights.Count; i++)
        {
            attenuation.w = 1;
            if (i == maxVisibleLights) break;
            VisibleLight light = cull.visibleLights[i];
            visibleLightColors[i] = light.finalColor;
            Vector4 shadow = Vector4.zero;

            if (light.lightType == LightType.Directional)
            {
                Vector4 v = light.localToWorld.GetColumn(2);
                v.x = -v.x;
                v.y = -v.y;
                v.z = -v.z;
                visibleLightDirectionOrPosition[i] = v;
                shadow = ConfigureShadows(i, light.light);
                shadow.z = 1;

                //当前如果属于主灯源并且主灯源为方向光的话 设置Setting_shadowCascades
                if (i == 0 && setting._shadowCascades > 0)
                {
                    shadowTileCount -= 1;
                    mainLightExitst = true;
                }

            }
            else  
            {
                //之取第四列作为位移信息导入
                visibleLightDirectionOrPosition[i] = light.localToWorld.GetColumn(3);
                attenuation.x = 1f / Mathf.Max(light.range * light.range, 0.0001f);
                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = light.localToWorld.GetColumn(2);
                    v.x = -v.x;
                    v.y = -v.y;
                    v.z = -v.z;
                    visibleLightSpotDirections[i] = v;

                    float outerRad = Mathf.Deg2Rad * 0.5f * light.spotAngle;
                    float outCos = Mathf.Cos(outerRad);
                    float outerTan = Mathf.Tan(outerRad);
                    float innerCos = Mathf.Cos(Mathf.Atan(46 / 64 * Mathf.Tan(outerTan)));
                    attenuation.z = 1f / Mathf.Max(innerCos - outCos, 0.001f);
                    attenuation.w = -outCos * attenuation.z;

                    //阴影属性设置
                    shadow = ConfigureShadows(i, light.light);
                }
            }
            visibleLightAttenuations[i] = attenuation;
            shadowData[i] = shadow;
        }
        for (; i < maxVisibleLights; i++){
            visibleLightColors[i] = Color.clear;
        }
        if (mainLightExitst||cull.visibleLights.Count > maxVisibleLights)
        {
            int[] lightIndices = cull.GetLightIndexMap();
            if (mainLightExitst) lightIndices[0] = -1;
            for (int l = maxVisibleLights; l < cull.visibleLights.Count; l++) lightIndices[i] = -1;
            cull.SetLightIndexMap(lightIndices);
        }
    }
    // 初始化镜头 清除上一帧画面，深度，设置灯光数据缓存
    void Setup()
    {

        if (cull.visibleLights.Count > 0)
        {
            ConfigureLights();
            if (mainLightExitst) RenderCascadsShadows(contex);
            else {
                buffer.DisableShaderKeyword(cascadedShadowSoftKeyword);
                buffer.DisableShaderKeyword(cascadedShadowHardKeyword);
            }
            if (shadowTileCount > 0) RenderShadows(contex);
            else
            {
                buffer.DisableShaderKeyword(shadowHardKeyWord);
                buffer.DisableShaderKeyword(shadowSoftKeyWord);
            }
        }
        else //不存在灯光时候的操作
        {
            buffer.SetGlobalVector(lightIndicesOffsetAndCountId, Vector4.zero);
            buffer.DisableShaderKeyword(shadowSoftKeyWord);
            buffer.DisableShaderKeyword(shadowHardKeyWord);
            buffer.DisableShaderKeyword(cascadedShadowHardKeyword);
            buffer.DisableShaderKeyword(cascadedShadowSoftKeyword);
        }

        //        ConfigureLights(); //

        contex.SetupCameraProperties(camera);
        CameraClearFlags clearFlag = camera.clearFlags;
        buffer.ClearRenderTarget((CameraClearFlags.Depth & clearFlag) != 0, (clearFlag & CameraClearFlags.Color) != 0, Color.clear);


        ExcuteBuffer();
    }

    void DrawVisibleGeometry(CullResults cull)
    {

        var drawsetting = new DrawRendererSettings(camera, new ShaderPassName("SRPDefaultUnlit"));
        // 通过这个渲染模式 灯光数量小于1时会导致工程崩溃
        if (cull.visibleLights.Count >= 1) drawsetting.rendererConfiguration = RendererConfiguration.PerObjectLightIndices8;

        var filterSetting = new FilterRenderersSettings(true);
        //设置渲染队列范围
        filterSetting.renderQueueRange = RenderQueueRange.opaque;
        //设置批处理 相关
        if (setting.dynamicBatching) drawsetting.flags = DrawRendererFlags.EnableDynamicBatching;
        if (setting.instancing) drawsetting.flags |= DrawRendererFlags.EnableInstancing;
        //设置渲染排序方法
        drawsetting.sorting.flags = SortFlags.CommonOpaque;
        //开始渲染非剔除物体
        contex.DrawRenderers(cull.visibleRenderers, ref drawsetting, filterSetting);
        //渲染天空盒
        contex.DrawSkybox(camera);

        drawsetting.sorting.flags = SortFlags.CommonTransparent;
        filterSetting.renderQueueRange = RenderQueueRange.transparent;
        contex.DrawRenderers(cull.visibleRenderers, ref drawsetting, filterSetting);

    }


    [Conditional("DEVELOPMENT_BUILD"),Conditional("UNITY_EDITOR")]
    void DrawDefaultPipeline(ScriptableRenderContext contex, Camera camera)
    {
        if (errorMaterial == null)
        {
            Shader errorShader = Shader.Find("Hidden/InternalErrorShader");
            errorMaterial = new Material(errorShader)
            {
                hideFlags = HideFlags.HideAndDontSave
            };
        }
        var drawSetting = new DrawRendererSettings(camera, new ShaderPassName("ForwardBase"));
        drawSetting.SetShaderPassName(1, new ShaderPassName("Always"));
        drawSetting.SetShaderPassName(2, new ShaderPassName("PrepassBase"));
        drawSetting.SetShaderPassName(3, new ShaderPassName("Vertex"));
        drawSetting.SetShaderPassName(4, new ShaderPassName("VertexLMRGBM"));
        drawSetting.SetShaderPassName(5, new ShaderPassName("VertexLM"));
        drawSetting.SetOverrideMaterial(errorMaterial,0);
        var filterSetting = new FilterRenderersSettings(true);
        contex.DrawRenderers(cull.visibleRenderers, ref drawSetting, filterSetting);
    }

    void ExcuteBffer(CommandBuffer BUFFER)
    {
        contex.ExecuteCommandBuffer(BUFFER);
        BUFFER.Clear();
    }
    void ExcuteBuffer()
    {
        contex.ExecuteCommandBuffer(buffer);
        buffer.Clear();
    }
    void Submit()
    {
        contex.Submit();
    }
}
